package com.dny.asmtop;

import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.commons.GeneratorAdapter;
import jdk.internal.org.objectweb.asm.commons.Method;

import java.util.List;
import java.util.Map;

/**
 * Created by jlutt on 2018-01-15.
 * 方法指令上下文
 * @author jlutt
 */
public class MethodContext {

  private final ASMClassLoader classLoader;

  //慢点就慢点吧，反正一般是启动的时候生成
  //asm封装的methodvisitor
  private final GeneratorAdapter mv;

  private final Type thisType;

  private final Method method;

  private final Class<?> mainClass;

  private final List<Class<?>> otherClasses;

  private final Map<String, Class<?>> fields;

  private final Map<String, Object> staticConstants;

  private final Type[] argumentTypes;

  private final Map<Method, Command> methods;

  private final Map<Method, Command> staticMethods;

  public MethodContext(ASMClassLoader classLoader,
                       GeneratorAdapter mv,
                       Type thisType,
                       Class<?> mainClass,
                       List<Class<?>> otherClasses,
                       Map<String, Class<?>> fields,
                       Map<String, Object> staticConstants,
                       Type[] argumentTypes,
                       Method method,
                       Map<Method, Command> methods,
                       Map<Method, Command> staticMethods) {
    this.classLoader = classLoader;
    this.mv = mv;
    this.thisType = thisType;
    this.method = method;
    this.mainClass = mainClass;
    this.otherClasses = otherClasses;
    this.fields = fields;
    this.staticConstants = staticConstants;
    this.argumentTypes = argumentTypes;
    this.methods = methods;
    this.staticMethods = staticMethods;
  }

  public ASMClassLoader getClassLoader() {
    return classLoader;
  }

  public GeneratorAdapter getGeneratorAdapter() {
    return mv;
  }

  public Type getThisType() {
    return thisType;
  }

  public Method getMethod() {
    return method;
  }

  public Class<?> getMainClass() {
    return mainClass;
  }

  public List<Class<?>> getOtherClasses() {
    return otherClasses;
  }

  public Map<String, Class<?>> getFields() {
    return fields;
  }

  public Map<String, Object> getStaticConstants() {
    return staticConstants;
  }

  public void addStaticConstant(String field, Object value) {
    this.staticConstants.put(field, value);
  }

  public Type[] getArgumentTypes() {
    return argumentTypes;
  }

  public Type getArgumentType(int argument) {
    return argumentTypes[argument];
  }

  public Map<Method, Command> getMethods() {
    return methods;
  }

  public Map<Method, Command> getStaticMethods() {
    return staticMethods;
  }
}
